﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ingenious.Owl.Linq
{
    #region Subject URI
    /// <summary>
    /// Specifies the subject URI to associate with a .NET type
    /// </summary>
    public class SubjectAttribute : Attribute
    {
        private readonly Uri m_subjectUri;

        #region Object Lifetime
        public SubjectAttribute(string subjectUri)
        {
            if (string.IsNullOrEmpty(subjectUri))
            {
                throw new ArgumentException("subjectUri cannot be null or empty", "subjectUri");
            }

            if (!Uri.TryCreate(subjectUri, UriKind.RelativeOrAbsolute, out m_subjectUri))
            {
                throw new ArgumentException("subjectUri is not a valid URI string", "subjectUri");
            }
        }

        public SubjectAttribute(Uri subjectUri)
        {
            if (subjectUri == null)
            {
                throw new ArgumentNullException("subjectUri");
            }

            m_subjectUri = subjectUri;
        }
        #endregion

        #region Properties
        public Uri Uri
        {
            get { return m_subjectUri; }
        }
        #endregion
    }
    #endregion

    #region Predicate URI
    /// <summary>
    /// Specifies the edge predicate URI to associate with a .NET property
    /// An edge predicate is one without any subject group reference in the known graph
    /// </summary>
    public class EdgePredicateAttribute : Attribute
    {
        private readonly Uri m_predicateUri;

        #region Object Lifetime
        public EdgePredicateAttribute(string predicateUri)
        {
            if (string.IsNullOrEmpty(predicateUri))
            {
                throw new ArgumentException("predicateUri cannot be null or empty", "predicateUri");
            }

            if (!Uri.TryCreate(predicateUri, UriKind.RelativeOrAbsolute, out m_predicateUri))
            {
                throw new ArgumentException("predicateUri is not a valid URI string", "predicateUri");
            }
        }
        #endregion
    }

    /// <summary>
    /// Specifies the predicate URI to associate with a .NET property
    /// </summary>
    public class PredicateAttribute : Attribute
    {
        private readonly Uri m_predicateUri;

        #region Object Lifetime
        public PredicateAttribute(string predicateUri)
        {
            if (string.IsNullOrEmpty(predicateUri))
            {
                throw new ArgumentException("predicateUri cannot be null or empty", "predicateUri");
            }

            if (!Uri.TryCreate(predicateUri, UriKind.RelativeOrAbsolute, out m_predicateUri))
            {
                throw new ArgumentException("predicateUri is not a valid URI string", "predicateUri");
            }
        }
        #endregion

        #region Properties
        public Uri Uri
        {
            get { return m_predicateUri; }
        }
        #endregion
    }
    #endregion

    #region Type Attribute
    /// <summary>
    /// Specifies an RDF type (shorthand for specifying as a predicate)
    /// </summary>
    public class TypeAttribute : Attribute
    {
        private readonly Uri m_typeUri;

        #region Object Lifetime
        public TypeAttribute(Uri typeUri)
        {
            if (typeUri == null)
            {
                throw new ArgumentNullException("typeUri");
            }

            m_typeUri = typeUri;
        }

        public TypeAttribute(string typeUri)
        {
            if (string.IsNullOrEmpty(typeUri))
            {
                throw new ArgumentException("typeUri cannot be null or empty", "typeUri");
            }

            if (!Uri.TryCreate(typeUri, UriKind.RelativeOrAbsolute, out m_typeUri))
            {
                throw new ArgumentException("typeUri is not a valid URI string", "typeUri");
            }
        }
        #endregion

        #region Properties
        public Uri TypeUri
        {
            get { return m_typeUri; }
        }
        #endregion
    }
    #endregion
}
